﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Serialization;
using Conteinerid.Aspects.Exceptions;


namespace Conteinerid.Aspects
{
    public interface IAspect
    {
        bool MustApply(MemberInfo member);

        bool ExecutarAntes(MemberInfo member, params object[] parametros);
        
        void ExecutarApos(MemberInfo member, params object[] parametros);

        void ExecutarAoOcorrerErro(Exception ex, MemberInfo member, params object[] parametros);
    }

    public abstract class BaseAdvice:IAspect
    {

        #region IAspect Members
        public bool ExecutarAntes(MemberInfo member, params object[] parametros)
        {
            try
            {
                return AoEntrar(member, parametros);
            }
            catch (Exception ex)
            {
                throw new AspectException(string.Format("{0}.{1} on {2}.{3}", GetType().FullName, "ExecutarAntes",member.DeclaringType.FullName,member.Name), ex);
            }
        }

        public void ExecutarApos(MemberInfo member, params object[] parametros)
        {
            try
            {
                AoSair(member,parametros);
            }
            catch (Exception ex)
            {
                throw new AspectException(string.Format("{0}.{1} on {2}.{3}", GetType().FullName, "ExecutarApos", member.DeclaringType.FullName, member.Name), ex);
            }
        }

        public void ExecutarAoOcorrerErro(Exception ex, MemberInfo member, params object[] parametros)
        {
            try
            {
                AoOcorrerErro(member, parametros);
            }
            catch (Exception exOnError)
            {
                throw new AspectException(string.Format("{0}.{1} on {2}.{3}", GetType().FullName, "ExecutarAoOcorrerErro", member.DeclaringType.FullName, member.Name), exOnError);
            }
        }
        #endregion

        protected abstract bool AoEntrar(MemberInfo member, params object[] parametros);
        protected abstract void AoSair(MemberInfo member, params object[] parametros);
        protected abstract void AoOcorrerErro(MemberInfo member, params object[] parametros);


        #region IAspect Members

        public abstract bool MustApply(MemberInfo member);

        #endregion
    }
}
